package lms.dwr.demo.service.impl;

import lms.dwr.demo.common.DAOException;
import lms.dwr.demo.common.ServiceException;
import lms.dwr.demo.dao.DAOUser;
import lms.dwr.demo.model.ModelUser;
import lms.dwr.demo.service.ServiceUser;
import lms.dwr.demo.utils.StringUtils;
import lms.dwr.demo.web.component.pagination.PaginationSupport;

import org.apache.log4j.Logger;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;

/**
 * The implementation of account service
 * 
 * @author Jeccy.Zhao
 *
 */
public class ServiceUserImpl
extends ServiceBaseImpl implements ServiceUser
{
	
	/**
	 * The LOGGER
	 */
	private static final Logger LOGGER = Logger.getLogger(ServiceUserImpl.class);
	
	/**
	 * The account repository
	 */
	private DAOUser daoUser;
	
	/*
	 * (non-Javadoc)
	 * @see com.lzcp.service.ServiceAccount#saveOrUpdate(com.lzcp.model.ModelUser)
	 */
	@Override
	public String saveOrUpdate(ModelUser account) 
			throws ServiceException
	{
		try
		{
			daoUser.saveOrUpdate(account);
			
			return account.getId();
		} 
		catch (DAOException e)
		{
			LOGGER.error("The account entity saves/updates failed" , e);
			return null;
		}
		catch (Exception e)
		{
			throw new ServiceException("The account entity saves/updates failed", e);
		}
	}
	
	/*
	 * (non-Javadoc)
	 * @see com.lzcp.service.ServiceAccount#removeAccount(java.lang.String)
	 */
	@Override
	public boolean removeAccount(String id) 
			throws ServiceException
	{
		return this.removeAccount(this.getAccountById(id));
	}
	
	/*
	 * (non-Javadoc)
	 * @see com.lzcp.service.ServiceAccount#validateAccountActivationCode(java.lang.String, java.lang.String)
	 */
	@Override
	public boolean isActivationCodeValid (String accountName, 
			String activationCode) throws ServiceException
	{
		try
		{
			ModelUser account = this.daoUser.getAccountByName(accountName);
			if (account != null)
			{
				return account.getUserActivationCode().equals(activationCode);
			}
		}
		catch (DAOException e)
		{
			LOGGER.error("The activation code is invalid with the specified account name: " + accountName , e);
		}
		catch (Exception e)
		{
			throw new ServiceException("The activation code is invalid with the specified account name: " + accountName, e);
		}
		
		return false;
	}
	
	/*
	 * (non-Javadoc)
	 * @see com.lzcp.service.ServiceAccount#removeAccount(com.lzcp.model.ModelUser)
	 */
	@Override
	public boolean removeAccount(ModelUser account) 
			throws ServiceException
	{
		try
		{
			daoUser.remove(account);
			
			return true;
		} 
		catch (DAOException e)
		{
			LOGGER.error("The account entity removes failed" , e);
			return false;
		}
		catch (Exception e)
		{
			throw new ServiceException("The account entity removes failed", e);
		}
	}
	
	/*
	 * (non-Javadoc)
	 * @see com.lzcp.service.ServiceAccount#getAccount(java.lang.String, java.lang.String)
	 */
	@Override
	public ModelUser getAccountByUserNameAndPwd(String userName, String password)
			throws ServiceException
	{
		if (StringUtils.isNotEmpty(userName, password))
		{
			try
			{
				return daoUser.getAccountByNameAndPwd(userName, password);
			} 
			catch (DAOException e)
			{
				LOGGER.error("The user name or passsword is invalid: " + userName , e);
				return null;
			}
			catch (Exception e)
			{
				throw new ServiceException("The user name or passsword is invalid: " + userName, e);
			}
		}
		
		return null;
	}
	
	/*
	 * (non-Javadoc)
	 * @see com.lzcp.service.ServiceAccount#getAccount(java.lang.String)
	 */
	@Override
	public ModelUser getAccountByUserName(String userName) throws ServiceException
	{
		if (StringUtils.isNotEmpty(userName))
		{
			try
			{
				return daoUser.getAccountByName(userName);
			} 
			catch (DAOException e)
			{
				LOGGER.error("The user does not exit: " + userName , e);
				return null;
			}
			catch (Exception e)
			{
				throw new ServiceException("The user does not exit: " + userName, e);
			}
		}
		
		return null;
	}
	
	/*
	 * (non-Javadoc)
	 * @see com.lzcp.service.ServiceAccount#getAccountById(java.lang.String)
	 */
	@Override
	public ModelUser getAccountById(String id) throws ServiceException
	{
		if (StringUtils.isNotEmpty(id))
		{
			try
			{
				return daoUser.get(id);
			} 
			catch (DAOException e)
			{
				LOGGER.error("Obtains account entity by id failed: " + id , e);
				return null;
			}
			catch (Exception e)
			{
				throw new ServiceException("Obtains account entity by id failed: " + id, e);
			}
		}
		
		return null;
	}
	
	/*
	 * (non-Javadoc)
	 * @see com.lzcp.service.ServiceAccount#getAccountPage(com.lzcp.model.ModelUser, int, int, java.lang.String, java.lang.Boolean)
	 */
	@Override
	public PaginationSupport<ModelUser> getAccountPage(ModelUser account,
			int pageSize, int startIndex, String order, Boolean isDesc)
			throws ServiceException
	{
		DetachedCriteria criteria = DetachedCriteria.forClass(ModelUser.class);
		
		if (account != null)
		{
			if(account.getUserName() != null && !"".equals(account.getUserName()))
			{
				criteria.add(Restrictions.eq("userName", account.getUserName()));
			}
			
			if (account.getUserType() != null)
			{
				criteria.add(Restrictions.eq("userType", account.getUserType()));
			}
			
			if (account.getUserStatus() != null)
			{
				criteria.add(Restrictions.eq("userStatus", account.getUserStatus()));
			}
		}
		
		if(StringUtils.isNotEmpty(order))
		{
			if(isDesc == null || !isDesc)
			{
				criteria.addOrder(Order.desc(order));
			}
			else
			{
				criteria.addOrder(Order.asc(order));
			}
		}
		else
		{
			criteria.addOrder(Order.desc("id"));
		}
		
		try 
		{
			return daoUser.findPageByCriteria(criteria, pageSize, startIndex);
		} 
		catch (DAOException e) 
		{
			LOGGER.error("Obtains account with pagination failed!" , e);
			return null;
		} 
		catch (Exception e)
		{
			throw (new ServiceException("Obtains account with pagination failed!", e));
		}
	}
	
	public static Logger getLogger()
	{
		return LOGGER;
	}

	public void setdaoUser(DAOUser daoUser)
	{
		this.daoUser = daoUser;
	}

	public DAOUser getDaoUser()
	{
		return daoUser;
	}

}
